/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 adventure_spell_effect.h

	$Header: /heroes4/adventure_spell_effect.h $

	$NoKeywords: $

 ************************************************************************/

#if !defined( ADVENTURE_SPELL_EFFECT_H_INCLUDED )
#define ADVENTURE_SPELL_EFFECT_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <assert.h>

#include "adventure_object.h"
#include "animation_ptr.h"
#include "footprint.h"
#include "idle_processor.h"
#include "sized_int_types.h"

// --------------------------------------------------------------------------
// t_adventure_spell_effect class
// --------------------------------------------------------------------------

class t_adventure_spell_effect
	:	public t_adventure_object,
		private t_footprint
{
public:
	// Constructor
	t_adventure_spell_effect(
		t_adventure_object const &	target,
		bool						underlay );

	// Member functions
	virtual void				accept( t_visitor & visitor );
	virtual void				accept( t_visitor & visitor ) const;
	virtual bool				animates() const;
	virtual t_clone_ptr			clone() const;
	virtual void				draw_shadow_to(
									t_uint32				current_time, 
									t_screen_rect const &	source_rect, 
									t_abstract_bitmap16 &	dest,
									t_screen_point const &	dest_point ) const;
	virtual void				draw_subimage_to(
									int						subimage_num,
									t_uint32				current_time,
									t_screen_rect const &	source_rect, 
									t_abstract_bitmap16 &	dest, 
									t_screen_point const &	dest_point,
									int						alpha ) const;
	void						finish();
	virtual t_footprint const &	get_footprint() const;
	virtual std::string			get_name() const;
	virtual t_screen_rect		get_rect() const = 0;
	virtual t_screen_rect		get_rect( t_uint32 current_time ) const;
	virtual t_screen_rect		get_shadow_rect() const;
	virtual t_screen_rect		get_shadow_rect( t_uint32 current_time ) const;
	virtual int					get_subimage_count() const;
	virtual int					get_subimage_depth_offset( int subimage_num ) const;
	virtual t_screen_rect		get_subimage_rect( int subimage_num ) const;
	virtual t_screen_rect		get_subimage_rect(
									int			subimage_num,
									t_uint32	time ) const;
	t_adventure_object const &	get_target() const;
	virtual bool				hit_test(
									t_uint32				current_time,
									t_screen_point const &	point ) const;
	virtual bool				needs_redrawing(
									t_uint32	last_update_time,
									t_uint32	current_time ) const;
	virtual void				run_modal();
	virtual bool				subimage_animates( int subimage_num ) const;
	virtual bool				subimage_is_underlay( int subimage_num ) const;
	virtual bool				subimage_needs_redrawing(
									int			subimage_num,
									t_uint32	last_update_time,
									t_uint32	current_time ) const;
	virtual bool				write_object( std::streambuf & stream ) const;

private:
	// Data members
	bool						m_done;
	t_adventure_object const &	m_target;
	bool						m_underlay;

	// Member functions
	virtual t_map_point_2d	get_size() const;
	virtual bool			is_cell_flat( t_map_point_2d const & point ) const;
	virtual bool			is_cell_impassable( t_map_point_2d const & point ) const;
	virtual bool			is_left_edge_trigger( t_map_point_2d const & point ) const;
	virtual bool			is_right_edge_trigger( t_map_point_2d const & point ) const;
	virtual bool			is_trigger_cell( t_map_point_2d const & point ) const;
};

// --------------------------------------------------------------------------
// t_adventure_spell_effect inline members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline t_adventure_object const & t_adventure_spell_effect::get_target() const
{
	return m_target;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
inline void t_adventure_spell_effect::finish()
{
	assert( !m_done );
	m_done = true;
}

// --------------------------------------------------------------------------
// t_adventure_animation_spell_effect class
// --------------------------------------------------------------------------

class t_adventure_animation_spell_effect
	:	public t_adventure_spell_effect,
		private t_idle_processor
{
public:
	// Constructor
	t_adventure_animation_spell_effect(
		t_adventure_object const &	target,
		bool						underlay,
		t_animation_ptr				animation_ptr );

	// Member functions
	virtual void			draw_to(
								t_uint32				current_time, 
								t_screen_rect const &	source_rect,
								t_abstract_bitmap16 &	dest, 
								t_screen_point const &	dest_point ) const;
	virtual t_screen_rect	get_rect() const;
	virtual void			run_modal();

private:
	// Data members
	t_animation_ptr	m_animation_ptr;
	int				m_cur_frame_num;
	t_uint32		m_start_time;

	// Member functions
	virtual void	on_idle();
};

// -----------------------------------------------------------------
// t_adv_magic_resistance_effect class
// -----------------------------------------------------------------

class t_adv_magic_resistance_effect : public t_adventure_animation_spell_effect
{
public:
	explicit t_adv_magic_resistance_effect( t_army const & army );
	
private:
	static t_animation_ptr get_animation();
};

// -----------------------------------------------------------------
// t_adv_mire_effect class
// -----------------------------------------------------------------

class t_adv_mire_effect : public t_adventure_animation_spell_effect
{
public:
	explicit t_adv_mire_effect( t_army const & army );
	
private:
	static t_animation_ptr get_animation();
};


#endif // !defined( ADVENTURE_SPELL_EFFECT_H_INCLUDED )
